home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / demo2.zoo / demo / ex / ex_v.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-30  |  8.7 KB  |  440 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6.  
  7. #ifndef lint
  8. static char *sccsid = "@(#)ex_v.c    7.9 (Berkeley) 3/9/87; 1.2 (Bellcore)    87/04/24";
  9. #endif not lint
  10.  
  11. #include "ex.h"
  12. #include "ex_re.h"
  13. #include "ex_tty.h"
  14. #include "ex_vis.h"
  15.  
  16. /*
  17.  * Entry points to open and visual from command mode processor.
  18.  * The open/visual code breaks down roughly as follows:
  19.  *
  20.  * ex_v.c    entry points, checking of terminal characteristics
  21.  *
  22.  * ex_vadj.c    logical screen control, use of intelligent operations
  23.  *        insert/delete line and coordination with screen image;
  24.  *        updating of screen after changes.
  25.  *
  26.  * ex_vget.c    input of single keys and reading of input lines
  27.  *        from the echo area, handling of \ escapes on input for
  28.  *        uppercase only terminals, handling of memory for repeated
  29.  *        commands and small saved texts from inserts and partline
  30.  *        deletes, notification of multi line changes in the echo
  31.  *        area.
  32.  *
  33.  * ex_vmain.c    main command decoding, some command processing.
  34.  *
  35.  * ex_voperate.c   decoding of operator/operand sequences and
  36.  *        contextual scans, implementation of word motions.
  37.  *
  38.  * ex_vops.c    major operator interfaces, undos, motions, deletes,
  39.  *        changes, opening new lines, shifts, replacements and yanks
  40.  *        coordinating logical and physical changes.
  41.  *
  42.  * ex_vops2.c    subroutines for operator interfaces in ex_vops.c,
  43.  *        insert mode, read input line processing at lowest level.
  44.  *
  45.  * ex_vops3.c    structured motion definitions of ( ) { } and [ ] operators,
  46.  *        indent for lisp routines, () and {} balancing. 
  47.  *
  48.  * ex_vput.c    output routines, clearing, physical mapping of logical cursor
  49.  *        positioning, cursor motions, handling of insert character
  50.  *        and delete character functions of intelligent and unintelligent
  51.  *        terminals, visual mode tracing routines (for debugging),
  52.  *        control of screen image and its updating.
  53.  *
  54.  * ex_vwind.c    window level control of display, forward and backward rolls,
  55.  *        absolute motions, contextual displays, line depth determination
  56.  */
  57.  
  58. jmp_buf venv;
  59. int    winch();
  60.  
  61. /*
  62.  * Enter open mode
  63.  */
  64. #ifdef u370
  65. char    atube[TUBESIZE+LBSIZE];
  66. #endif
  67. oop()
  68. {
  69.     register char *ic;
  70. #ifndef u370
  71.     char atube[TUBESIZE + LBSIZE];
  72. #endif
  73.     ttymode f;    /* mjm: was register */
  74.  
  75.     if (setjmp(venv)) {
  76.         setsize();
  77.         initev = (char *)0;
  78.         inopen = 0;
  79.         addr1 = addr2 = dot;
  80.     }
  81. #ifdef    SIGWINCH
  82.     (void)signal(SIGWINCH, winch);
  83. #endif
  84.     ovbeg();
  85.     if (peekchar() == '/') {
  86.         ignore(compile(ex_getchar(), 1));
  87.         savere(scanre);
  88.         if (execute(0, dot) == 0)
  89.             error("Fail|Pattern not found on addressed line");
  90.         ic = loc1;
  91.         if (ic > linebuf && *ic == 0)
  92.             ic--;
  93.     } else {
  94.         getDOT();
  95.         ic = vskipwh(linebuf);
  96.     }
  97.     newline();
  98.  
  99.     /*
  100.      * If overstrike then have to HARDOPEN
  101.      * else if can move cursor up off current line can use CRTOPEN (~~vi1)
  102.      * otherwise (ugh) have to use ONEOPEN (like adm3)
  103.      */
  104.     if (OS && !EO)
  105.         bastate = HARDOPEN;
  106.     else if (CA || UP)
  107.         bastate = CRTOPEN;
  108.     else
  109.         bastate = ONEOPEN;
  110.     setwind();
  111.  
  112.     /*
  113.      * To avoid bombing on glass-crt's when the line is too long
  114.      * pretend that such terminals are 160 columns wide.
  115.      * If a line is too wide for display, we will dynamically
  116.      * switch to hardcopy open mode.
  117.      */
  118.     if (state != CRTOPEN)
  119.         WCOLS = TUBECOLS;
  120.     if (!inglobal)
  121.         savevis();
  122.     vok(atube);
  123.     if (state != CRTOPEN)
  124.         COLUMNS = WCOLS;
  125.     Outchar = vputchar;
  126.     f = ostart();
  127.     if (state == CRTOPEN) {
  128.         if (outcol == UKCOL)
  129.             outcol = 0;
  130.         vmoveitup(1, 1);
  131.     } else
  132.         outline = destline = WBOT;
  133.     vshow(dot, NOLINE);
  134.     vnline(ic);
  135.     vmain();
  136.     if (state != CRTOPEN)
  137.         vclean();
  138.     Command = "open";
  139.     ovend(f);
  140. #ifdef    SIGWINCH
  141.     (void)signal(SIGWINCH, SIG_DFL);
  142. #endif
  143. }
  144.  
  145. ovbeg()
  146. {
  147.  
  148.     if (!value(OPEN))
  149.         error("Can't use open/visual unless open option is set");
  150.     if (inopen)
  151.         error("Recursive open/visual not allowed");
  152.     Vlines = lineDOL();
  153.     fixzero();
  154.     setdot();
  155.     pastwh();
  156.     dot = addr2;
  157. }
  158.  
  159. ovend(f)
  160.     ttymode f;
  161. {
  162.  
  163.     splitw++;
  164.     vgoto(WECHO, 0);
  165.     vclreol();
  166.     vgoto(WECHO, 0);
  167.     holdcm = 0;
  168.     splitw = 0;
  169.     ostop(f);
  170.     setoutt();
  171.     undvis();
  172.     COLUMNS = OCOLUMNS;
  173.     inopen = 0;
  174.     flusho();
  175.     netchHAD(Vlines);
  176. }
  177.  
  178. /*
  179.  * Enter visual mode
  180.  */
  181. vop()
  182. {
  183.     register int c;
  184. #ifndef u370
  185.     char atube[TUBESIZE + LBSIZE];
  186. #endif
  187.     ttymode f;    /* mjm: was register */
  188.  
  189.     if (!CA && UP == NOSTR) {
  190.         if (initev) {
  191. toopen:
  192.             merror("[Using open mode]");
  193.             putNFL();
  194.             oop();
  195.             return;
  196.         }
  197.         error("Visual needs addressible cursor or upline capability");
  198.     }
  199.     if (OS && !EO) {
  200.         if (initev)
  201.             goto toopen;
  202.         error("Can't use visual on a terminal which overstrikes");
  203.     }
  204.     if (!CL) {
  205.         if (initev)
  206.             goto toopen;
  207.         error("Visual requires clear screen capability");
  208.     }
  209.     if (NS && !SF) {
  210.         if (initev)
  211.             goto toopen;
  212.         error("Visual requires scrolling");
  213.     }
  214.     if (setjmp(venv)) {
  215.         setsize();
  216.         initev = (char *)0;
  217.         inopen = 0;
  218.         addr1 = addr2 = dot;
  219.     }
  220. #ifdef    SIGWINCH
  221.     (void)signal(SIGWINCH, winch);
  222. #endif
  223.     ovbeg();
  224.     bastate = VISUAL;
  225.     c = 0;
  226.     if (any(peekchar(), "+-^."))
  227.         c = ex_getchar();
  228.     pastwh();
  229.     vsetsiz(isdigit(peekchar()) ? getnum() : value(WINDOW));
  230.     setwind();
  231.     newline();
  232.     vok(atube);
  233.     if (!inglobal)
  234.         savevis();
  235.     Outchar = vputchar;
  236.     vmoving = 0;
  237.     f = ostart();
  238.     if (initev == 0) {
  239.         vcontext(dot, c);
  240.         vnline(NOSTR);
  241.     }
  242.     vmain();
  243.     Command = "visual";
  244.     ovend(f);
  245. #ifdef    SIGWINCH
  246.     (void)signal(SIGWINCH, SIG_DFL);
  247. #endif
  248. }
  249.  
  250. /*
  251.  * Hack to allow entry to visual with
  252.  * empty buffer since routines internally
  253.  * demand at least one line.
  254.  */
  255. fixzero()
  256. {
  257.  
  258.     if (dol == zero) {
  259.         register bool ochng = chng;
  260.  
  261.         vdoappend("");
  262.         if (!ochng)
  263.             ex_sync();
  264.         addr1 = addr2 = one;
  265.     } else if (addr2 == zero)
  266.         addr2 = one;
  267. }
  268.  
  269. /*
  270.  * Save lines before visual between unddol and truedol.
  271.  * Accomplish this by throwing away current [unddol,truedol]
  272.  * and then saving all the lines in the buffer and moving
  273.  * unddol back to dol.  Don't do this if in a global.
  274.  *
  275.  * If you do
  276.  *    g/xxx/vi.
  277.  * and then do a
  278.  *    :e xxxx
  279.  * at some point, and then quit from the visual and undo
  280.  * you get the old file back.  Somewhat weird.
  281.  */
  282. savevis()
  283. {
  284.  
  285.     if (inglobal)
  286.         return;
  287.     truedol = unddol;
  288.     saveall();
  289.     unddol = dol;
  290.     undkind = UNDNONE;
  291. }
  292.  
  293. /*
  294.  * Restore a sensible state after a visual/open, moving the saved
  295.  * stuff back to [unddol,dol], and killing the partial line kill indicators.
  296.  */
  297. undvis()
  298. {
  299.  
  300.     if (ruptible)
  301.         signal(SIGINT, onintr);
  302.     squish();
  303.     pkill[0] = pkill[1] = 0;
  304.     unddol = truedol;
  305.     unddel = zero;
  306.     undap1 = one;
  307.     undap2 = dol + 1;
  308.     undkind = UNDALL;
  309.     if (undadot <= zero || undadot > dol)
  310.         undadot = zero+1;
  311. }
  312.  
  313. /*
  314.  * Set the window parameters based on the base state bastate
  315.  * and the available buffer space.
  316.  */
  317. setwind()
  318. {
  319.  
  320.     WCOLS = COLUMNS;
  321.     switch (bastate) {
  322.  
  323.     case ONEOPEN:
  324.         if (AM)
  325.             WCOLS--;
  326.         /* fall into ... */
  327.  
  328.     case HARDOPEN:
  329.         basWTOP = WTOP = WBOT = WECHO = 0;
  330.         ex_ZERO = 0;
  331.         holdcm++;
  332.         break;
  333.  
  334.     case CRTOPEN:
  335.         basWTOP = LINES - 2;
  336.         /* fall into */
  337.  
  338.     case VISUAL:
  339.         ex_ZERO = LINES - TUBESIZE / WCOLS;
  340.         if (ex_ZERO < 0)
  341.             ex_ZERO = 0;
  342.         if (ex_ZERO > basWTOP)
  343.             error("Screen too large for internal buffer");
  344.         WTOP = basWTOP; WBOT = LINES - 2; WECHO = LINES - 1;
  345.         break;
  346.     }
  347.     state = bastate;
  348.     basWLINES = WLINES = WBOT - WTOP + 1;
  349. }
  350.  
  351. /*
  352.  * Can we hack an open/visual on this terminal?
  353.  * If so, then divide the screen buffer up into lines,
  354.  * and initialize a bunch of state variables before we start.
  355.  */
  356. vok(atube)
  357.     register char *atube;
  358. {
  359.     register int i;
  360.  
  361.     if (WCOLS == 1000)
  362.         serror("Don't know enough about your terminal to use %s", Command);
  363.     if (WCOLS > TUBECOLS)
  364.         error("Terminal too wide");
  365.     if (WLINES >= TUBELINES || WCOLS * (WECHO - ex_ZERO + 1) > TUBESIZE)
  366.         error("Screen too large");
  367.  
  368.     vtube0 = atube;
  369.     vclrbyte(atube, WCOLS * (WECHO - ex_ZERO + 1));
  370.     for (i = 0; i < ex_ZERO; i++)
  371.         vtube[i] = (char *) 0;
  372.     for (; i <= WECHO; i++)
  373.         vtube[i] = atube, atube += WCOLS;
  374.     for (; i < TUBELINES; i++)
  375.         vtube[i] = (char *) 0;
  376.     vutmp = atube;
  377.     vundkind = VNONE;
  378.     vUNDdot = 0;
  379.     OCOLUMNS = COLUMNS;
  380.     inopen = 1;
  381. #ifdef CBREAK
  382.     signal(SIGINT, vintr);
  383. #endif
  384.     vmoving = 0;
  385.     splitw = 0;
  386.     doomed = 0;
  387.     holdupd = 0;
  388.     Peek_key = 0;
  389.     vcnt = vcline = 0;
  390.     if (ex_vSCROLL == 0)
  391.         ex_vSCROLL = (value(WINDOW)+1)/2; /* round up so dft=6,11 */
  392. }
  393.  
  394. #ifdef CBREAK
  395. vintr()
  396. {
  397.     extern jmp_buf readbuf;
  398.     extern int doingread;
  399.  
  400.     signal(SIGINT, vintr);
  401.     if (vcatch)
  402.         onintr();
  403.     ungetkey(ATTN);
  404.     draino();
  405.     if (doingread) {
  406.         doingread = 0;
  407.         longjmp(readbuf, 1);
  408.     }
  409. }
  410. #endif
  411.  
  412. /*
  413.  * Set the size of the screen to size lines, to take effect the
  414.  * next time the screen is redrawn.
  415.  */
  416. vsetsiz(size)
  417.     int size;
  418. {
  419.     register int b;
  420.  
  421.     if (bastate != VISUAL)
  422.         return;
  423.     b = LINES - 1 - size;
  424.     if (b >= LINES - 1)
  425.         b = LINES - 2;
  426.     if (b < 0)
  427.         b = 0;
  428.     basWTOP = b;
  429.     basWLINES = WBOT - b + 1;
  430. }
  431.  
  432. /* #ifdef    SIGWINCH */
  433. winch()
  434. {
  435.     vsave();
  436.     ignore(setty(normf));
  437.     longjmp(venv, 1);
  438. }
  439. /* #endif */
  440.